Wherein I waste time on a repeat
I spent so much time today trying to count the points inside the lagoon by going along the edge and trying to smartly count the points inside per-row... when it is simply the exact same problem as in day 10—you need to calculate the area of a polygon. Though, unlike day 10, this time including the entire outline.
Once I had the realization, it was simply a matter of writing the whole shoelace/Pick's thing again. I haven't described it in my day 10 post yet, because it was a solution I found out about later; but the idea is this:
- calculate the "real" area of the shape using the Shoelace formula;
- using the inverse of Pick's theorem, go from the "real" area to the number of integer points inside the shape.
fn lagoon_size(input: &str, decode: bool) -> i64 {
let mut points = 1;
let mut pos = (0, 0);
let mut area = 0;
for (dir, count) in parse(input, decode) {
points += count;
let next_pos = match dir {
b'L' => (pos.0 - count, pos.1),
b'U' => (pos.0, pos.1 - count),
b'R' => (pos.0 + count, pos.1),
b'D' => (pos.0, pos.1 + count),
_ => unreachable!(),
};
area += pos.0 * next_pos.1 - pos.1 * next_pos.0;
pos = next_pos;
}
area / 2 + points / 2 + 1
}
It's very little code, and it's very efficient. I go through the instructions once, counting how many points the edge has, and doing the shoelace formula, at the same time. Then, at the end I turn area
into the number of points inside (area / 2 - points / 2 + 1
) plus the number of points on the shape, thus giving me the final result.
I can't believe it took me so long to do this, but sometimes you just forget things you should know.